 // Created by Jan Skansholm 2000 
 // This header file is intended for programs that use an MS_DOS console 
 // window to display data and read input. It gives correct input and 
 // output of all LATIN_1 letters, not only the letters a-z.
 // 
 // Include this file in the function main and make the  
 // following call at the beginning of the program. 
 //    dos_console(); 
 // Then all output will be translated from LATIN_1 code to MS_DOS code 850 
 // and all input from MS_DOS code 850 to LATIN_1. 
 // It is also possible to use an alternative MS-DOS code. 
 // You can make the call
 //    dos_console(n); 
 // where n is a code number, 437 for instance. 
 // This header file supports MS-DOS codes 850 and 437, but it is easy to  
 // extend the file with additional codes.

#ifndef _IODOS
#define _IODOS

#include <iostream>
#include <cstdio>


static const int _xx=63;    // undefined symbol, translate to '?'

static const int _from850[] =    // 850 -> Latin1
{  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
 199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197,
 201,230,198,244,246,242,251,249,255,214,220,248,163,216,215,102,
 225,237,243,250,241,209,170,176,191,174,172,189,188,161,171,187,
 _xx,_xx,_xx,124,_xx,193,194,192,169,_xx,_xx,_xx,_xx,162,165,_xx,
 _xx,_xx,_xx,_xx,_xx,_xx,227,195,_xx,_xx,_xx,_xx,_xx, 61,_xx,164,
 240,208,202,203,200,_xx,205,206,207,_xx,_xx,_xx,_xx,166,204,_xx,
 211,223,212,210,245,213,181,254,222,218,219,217,253,221,175,180,
  45,177, 61,190,182,167,247,184,176,168,183,185,179,178,_xx,_xx
};

static const int _to850[] =   // Latin1 -> 850
{  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
 _xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,
 _xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,
 _xx,173,189,156,207,190,221,245,249,184,166,174,170, 45,169,238,
 248,241,253,252,239,230,244,250,247,251,248,175,172,171,243,168,
 183,181,182,199,142,143,146,128,212,144,210,211,222,214,215,216,
 209,165,227,224,226,229,153,158,157,235,233,234,154,237,232,225,
 133,160,131,198,132,134,145,135,138,130,136,137,141,161,140,139,
 208,164,149,162,147,228,148,246,155,151,163,150,129,236,231,152
};

static const int _from437[] =    // 437 -> Latin1
{  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
 199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197,
 201,230,198,244,246,242,251,249,255,214,162,231,163,165,_xx,102,
 225,237,243,250,241,209,170,176,191,_xx,172,189,188,161,171,187,
 _xx,_xx,_xx,124,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,
 _xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx, 61,_xx,_xx,
 _xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,
 _xx,223,_xx,_xx,_xx,_xx,181,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,
 _xx,177,_xx,_xx,_xx,_xx,247,_xx,176,183,183,_xx,110,178,_xx,_xx
};

static const int _to437[] =   // Latin1 -> 437
{  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
 _xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,
 _xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,_xx,
 _xx,173,155,156,_xx,157,124, 21,_xx,_xx,166,174,170, 45,_xx,_xx,
 248,241,253,_xx,239,230, 20,250,_xx,_xx,248,175,172,171,_xx,168,
  65, 65, 65, 65,142,143,146,128, 69,144, 69, 69, 73, 73, 73, 73,
  68,165, 79, 79, 79, 79,153,120, 79, 79, 85, 85,154, 89, 80,225,
 133,160,131, 97,132,134,145,135,138,130,136,137,141,161,140,139,
 100,164,149,162,147,111,148,246,111,151,163,150,129,121,112,152
};


class _dos_streambuf : public std::streambuf {
public:
	_dos_streambuf(FILE *file, const int tin[], const int _tout[]) 
		: f(file), tab_in(tin), tab_out(_tout)
         {setg(buf, buf+1, buf+1);}
protected:
	virtual int underflow()   
           {setg(buf, buf, buf+1); return buf[0]=tab_in[fgetc(f)];}
	virtual int overflow (int c = EOF)
           {return fputc(tab_out[c], f);}
	virtual int pbackfail(int c = EOF)
           {return ungetc(c==EOF? tab_out[buf[0]] : tab_out[c], f);}
private:
	FILE *f;
	char buf[1];
	const int *tab_in;   // dos -> Latin1
    const int *tab_out;  // Latin1 -> dos
};


static void dos_console(int code=850) {  
  if (code == 850) {
    std::cin.rdbuf (new _dos_streambuf(stdin,  _from850, _to850));
    std::cout.rdbuf(new _dos_streambuf(stdout, _from850, _to850));
    std::cerr.rdbuf(new _dos_streambuf(stderr, _from850, _to850));
    std::clog.rdbuf(new _dos_streambuf(stdout, _from850, _to850));
  }
  else if (code == 437) {
    std::cin.rdbuf (new _dos_streambuf(stdin,  _from437, _to437));
    std::cout.rdbuf(new _dos_streambuf(stdout, _from437, _to437));
    std::cerr.rdbuf(new _dos_streambuf(stderr, _from437, _to437));
    std::clog.rdbuf(new _dos_streambuf(stdout, _from437, _to437));
  }
  // If another coding is used two additional arrays
  // could be defined and given as arguments.
  else
	  std::cerr << "Code " << code << " not supported." << std::endl;
}

#endif


